﻿using Microsoft.EntityFrameworkCore;
using RotovapPlatform.Domain.Business.Interfaces;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Infrastructure.Common.Data;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace RotovapPlatform.Infrastructure.Business.ExperimentGroups;

/// <summary>
/// 实验组仓储实现
/// </summary>
public class ExperimentGroupRepository : IExperimentGroupRepository
{
	private readonly ExperimentGroupDbContext _context;

	public ExperimentGroupRepository(ExperimentGroupDbContext context)
	{
		_context = context;
		Debug.WriteLine($"ExperimentGroupRepository created with context: {context.GetType().Name}");
	}

	public async Task<IEnumerable<ExperimentGroup>> GetAllAsync()
	{
		try
		{
			return await _context.ExperimentGroups
				.Include(g => g.Experiments)  // 显式加载实验集合
				.AsNoTracking()
				.ToListAsync();
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in GetAllAsync: {ex.Message}");
			throw;
		}
	}

	public async Task<ExperimentGroup> GetByIdAsync(Guid groupId)
	{
		try
		{
			return await _context.ExperimentGroups
				.Include(g => g.Experiments)
				.AsNoTracking()
				.FirstOrDefaultAsync(g => g.GroupId == groupId);
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in GetByIdAsync: {ex.Message}");
			throw;
		}
	}

	public async Task AddAsync(ExperimentGroup group, bool updateExperiments = false)
	{
		try
		{
			// 添加调试日志
			Debug.WriteLine($"AddAsync: group.Experiments.Count = {group.Experiments.Count}, updateExperiments = {updateExperiments}");

			// 如果不需要更新实验数据，则清空实验集合
			if (!updateExperiments && group.Experiments.Count > 0)
			{
				Debug.WriteLine("跳过实验数据处理，清空实验集合");
				group.Experiments.Clear();
			}
			else if (group.Experiments.Count > 0)
			{
				foreach (var experiment in group.Experiments)
				{
					Debug.WriteLine($"AddAsync: experiment.ExecutionParameters = {(experiment.ExecutionParameters == null ? "null" : "有值")}");
					if (experiment.ExecutionParameters != null)
					{
						Debug.WriteLine($"  MaterialName = {experiment.ExecutionParameters.MaterialName}");
						Debug.WriteLine($"  MaterialLocations.Count = {experiment.ExecutionParameters.MaterialLocations?.Count ?? 0}");
						Debug.WriteLine($"  ProductParameters.Count = {experiment.ExecutionParameters.ProductParameters?.Count ?? 0}");
					}
				}
			}

			// 先分离所有实体
			_context.ChangeTracker.Clear();

			// 添加实验组
			await _context.ExperimentGroups.AddAsync(group);
			await _context.SaveChangesAsync();

			Debug.WriteLine($"Added ExperimentGroup with ID: {group.GroupId}");
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in AddAsync: {ex.Message}");
			throw;
		}
	}

	public async Task UpdateAsync(ExperimentGroup group, bool updateExperiments = false)
	{
		try
		{
			// 添加调试日志
			Debug.WriteLine($"UpdateAsync: group.Experiments.Count = {group.Experiments.Count}, updateExperiments = {updateExperiments}");
			foreach (var experiment in group.Experiments)
			{
				Debug.WriteLine($"UpdateAsync: experiment.ExecutionParameters = {(experiment.ExecutionParameters == null ? "null" : "有值")}");
				if (experiment.ExecutionParameters != null)
				{
					Debug.WriteLine($"  MaterialName = {experiment.ExecutionParameters.MaterialName}");
					Debug.WriteLine($"  MaterialLocations.Count = {experiment.ExecutionParameters.MaterialLocations?.Count ?? 0}");
					Debug.WriteLine($"  ProductParameters.Count = {experiment.ExecutionParameters.ProductParameters?.Count ?? 0}");
				}
			}

			// 先分离所有实体
			_context.ChangeTracker.Clear();

			// 检查实验组是否存在
			var existingGroup = await _context.ExperimentGroups
				.AsNoTracking()
				.FirstOrDefaultAsync(g => g.GroupId == group.GroupId);

			if (existingGroup == null)
			{
				Debug.WriteLine($"Warning: ExperimentGroup with ID {group.GroupId} not found in database");
				// 如果不存在，则添加新的实验组
				await _context.ExperimentGroups.AddAsync(group);
			}
			else
			{
				// 如果存在，则更新实验组
				_context.Entry(group).State = EntityState.Modified;

				// 只有在显式指定时才处理实验集合
				if (updateExperiments && group.Experiments != null && group.Experiments.Count > 0)
				{
					Debug.WriteLine($"处理实验集合，共 {group.Experiments.Count} 个实验");
					foreach (var experiment in group.Experiments)
					{
						// 检查实验是否已存在
						var existingExperiment = await _context.Experiments
							.AsNoTracking()
							.FirstOrDefaultAsync(e => e.ExperimentId == experiment.ExperimentId);

						if (existingExperiment == null)
						{
							// 如果不存在，则添加新的实验
							_context.Entry(experiment).State = EntityState.Added;
							Debug.WriteLine($"添加新实验: {experiment.ExperimentId}");
						}
						else
						{
							// 如果存在，则更新实验
							_context.Entry(experiment).State = EntityState.Modified;
							Debug.WriteLine($"更新现有实验: {experiment.ExperimentId}");
						}
					}
				}
				else
				{
					Debug.WriteLine("跳过实验数据处理");
				}
			}

			await _context.SaveChangesAsync();
			Debug.WriteLine($"Updated ExperimentGroup with ID: {group.GroupId}");

			// 查询更新后的实验组，检查执行参数
			var updatedGroup = await _context.ExperimentGroups
				.Include(g => g.Experiments)
				.FirstOrDefaultAsync(g => g.GroupId == group.GroupId);

			if (updatedGroup != null)
			{
				Debug.WriteLine($"查询更新后的实验组: updatedGroup.Experiments.Count = {updatedGroup.Experiments.Count}");
				foreach (var exp in updatedGroup.Experiments)
				{
					Debug.WriteLine($"  Experiment.ID = {exp.ExperimentId}, ExecutionParameters = {(exp.ExecutionParameters == null ? "null" : "有值")}");
				}
			}
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in UpdateAsync: {ex.Message}");
			throw;
		}
	}

	public async Task DeleteAsync(Guid groupId)
	{
		try
		{
			var group = await _context.ExperimentGroups.FindAsync(groupId);
			if (group != null)
			{
				_context.ExperimentGroups.Remove(group);
				await _context.SaveChangesAsync();
				Debug.WriteLine($"Deleted ExperimentGroup with ID: {groupId}");
			}
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in DeleteAsync: {ex.Message}");
			throw;
		}
	}

	public async Task<ExperimentGroup> GetByNameAsync(string groupName)
	{
		try
		{
			return await _context.ExperimentGroups
				.FirstOrDefaultAsync(g => g.GroupName == groupName);
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in GetByNameAsync: {ex.Message}");
			throw;
		}
	}

	public async Task<bool> ExistsByNameAsync(string groupName)
	{
		try
		{
			return await _context.ExperimentGroups
				.AnyAsync(g => g.GroupName == groupName);
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in ExistsByNameAsync: {ex.Message}");
			throw;
		}
	}

	public async Task<IEnumerable<ExperimentGroup>> GetByTimeRangeAsync(DateTime startTime, DateTime endTime)
	{
		try
		{
			return await _context.ExperimentGroups
				.Where(g => g.CreatedTime >= startTime && g.CreatedTime <= endTime)
				.ToListAsync();
		}
		catch (Exception ex)
		{
			Debug.WriteLine($"Error in GetByTimeRangeAsync: {ex.Message}");
			throw;
		}
	}

}